package com.clt.ess.crypt;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.Date;
import java.util.Enumeration;
import java.util.Vector;

import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Boolean;
import org.bouncycastle.asn1.ASN1Choice;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.BERTags;
import org.bouncycastle.asn1.DERApplicationSpecific;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DEREncodableVector;
import org.bouncycastle.asn1.DERGeneralizedTime;
import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERUTF8String;
import org.bouncycastle.asn1.x509.Extension;

import sun.misc.BASE64Decoder;

public class TestAsn1 {
	private static ASN1EncodableVector CreateSealHead(String sealTag,int iVersion,String makerID){
		ASN1EncodableVector v = new ASN1EncodableVector();
		
		DERIA5String ia5String = new DERIA5String(sealTag);
		v.add(ia5String);
		v.add(new ASN1Integer(iVersion));
		
		DERIA5String ia5String2 = new DERIA5String(makerID);
		v.add(ia5String2);
		
		return v;
	}
	
	private static ASN1EncodableVector CreatePictureInfo(String sPicType,byte[] bPic,int iW,int iH){
		ASN1EncodableVector v = new ASN1EncodableVector();
		DEROctetString octString = new DEROctetString(bPic);
		v.add(octString);
		v.add(new ASN1Integer(iW));
		v.add(new ASN1Integer(iH));
		return v;
	}
	
	private static ASN1EncodableVector CreatePorpertyInfo(int iSealType,String sSealName,int iListType,ASN1EncodableVector certList,String sealMakeDate,String sealBeginDate,String sealEndDate){
		ASN1EncodableVector v = new ASN1EncodableVector();
		v.add(new ASN1Integer(iSealType));
		DERUTF8String utf8String = new DERUTF8String(sSealName);
		v.add(utf8String);
		v.add(new ASN1Integer(iListType));
		DERSequence certs = new DERSequence(certList);
		v.add(certs);
		DERGeneralizedTime t1 = new DERGeneralizedTime(sealMakeDate);
		DERGeneralizedTime t2 = new DERGeneralizedTime(sealBeginDate);
		DERGeneralizedTime t3 = new DERGeneralizedTime(sealEndDate);
		v.add(t1);
		v.add(t2);
		v.add(t3);
		return v;
	}
	
	
	private static ASN1EncodableVector CreateCertList(Vector<String> vCert){
		ASN1EncodableVector v = new ASN1EncodableVector();
		BASE64Decoder d64 = new BASE64Decoder();
		for(int i=0;i<vCert.size();i++)
		{
			String sCert = vCert.elementAt(i);
			try {
				byte[] bCert = d64.decodeBuffer(sCert);
				DEROctetString octString = new DEROctetString(bCert);
				v.add(octString);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return v;
	}
	
	
	private static ASN1EncodableVector CreateSealInfo(ASN1EncodableVector header,String sealID,ASN1EncodableVector property,ASN1EncodableVector picInfo,ASN1EncodableVector extData ){
		ASN1EncodableVector v = new ASN1EncodableVector();
		DERSequence derSeq = new DERSequence(header);
		v.add(derSeq);
		DERIA5String ia5String = new DERIA5String(sealID);
		v.add(ia5String);
		derSeq = new DERSequence(property);
		v.add(derSeq);
		derSeq = new DERSequence(picInfo);
		v.add(derSeq);
		derSeq = new DERSequence(extData);
		v.add(derSeq);
		return v;
	}
	
	private static ASN1EncodableVector CreateExData(Vector<ExDataStru> ve) throws UnsupportedEncodingException{
		ASN1EncodableVector vEx = new ASN1EncodableVector();
		for(int i=0;i<ve.size();i++){
			ExDataStru exStru = ve.elementAt(i);
			
			String oidSEx = exStru.oid;
			ASN1ObjectIdentifier oidex = new ASN1ObjectIdentifier(oidSEx);
			String octsEx = exStru.sData;
			DEROctetString octStringEx = new DEROctetString(octsEx.getBytes("utf8"));
			Extension ex1 = new Extension(oidex, exStru.blOption, octStringEx);
			vEx.add(ex1);
		}
		return vEx;
	}
	
	
	public static void CreateSeal(
			String 		sealTag,					//电子印章标识
			int 		iVersion,					//版本号
			String		sMakerID,					//印章厂商ID
			String 		sSealID,					//印章唯一赋码
			int			iSealType,					//印章类型
			String		sSealName,					//印章名称
			int			iListType,					//证书列表类型
			String[]	sCertList,					//可签章证书列表（BASE64）
			String		sMakeDate,					//制作日期
			String		sValidBegin,				//印章有效期起始
			String		sValidEnd,					//印章有效期终止
			String		sPicType,					//图像类型
			byte[]		bPicData,					//图像数据
			int			iPicWidth,					//图像显示宽度（毫米）
			int			iPicHeight,					//图像显示高度（毫米)
			Vector<String>	vCert,					//可签证书列表
			Vector<ExDataStru> exDatas,				//扩展字段,
			byte[]		bMakerCert,					//制章者证书
			String		signAlgID					//签名算法标识
			){
		
		//印章头
		ASN1EncodableVector header = CreateSealHead(sealTag,iVersion,sMakerID);
		//可签印章列表
		ASN1EncodableVector certList = CreateCertList(vCert);
		
		ASN1EncodableVector propInfo = CreatePorpertyInfo(iSealType,sSealName,iListType,certList,sMakeDate,sValidBegin,sValidEnd);
		
		ASN1EncodableVector picInfo = CreatePictureInfo(sPicType,bPicData,iPicWidth,iPicHeight);
		
		ASN1EncodableVector extensionDates = null;
		try {
			extensionDates = CreateExData(exDatas);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		ASN1EncodableVector sealInfo = CreateSealInfo(header,sSealID,propInfo,picInfo,extensionDates);
		DERSequence der = new DERSequence(sealInfo);
		byte[] bSealInfo = null;
		try {
			bSealInfo = der.getEncoded("DER");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		byte[] bSignVal = null;
		
		ASN1EncodableVector seal = new ASN1EncodableVector();
		seal.add(new DERSequence(sealInfo));
		seal.add(new DEROctetString(bMakerCert));
		seal.add(new ASN1ObjectIdentifier(signAlgID));
		seal.add(new DERBitString(bSignVal));
		
		
		
	}
			
//			,byte[] bMakerCert,byte[] bSigVal){
//		String algOid = "1.2.156.10197.1.501";
//		ASN1EncodableVector v = new ASN1EncodableVector();
//		
//	}

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		ASN1EncodableVector v = new ASN1EncodableVector();
		BigInteger r = new BigInteger("891001231");
		v.add(new ASN1Integer(r));
		
		ASN1Boolean asn1Boolean = ASN1Boolean.getInstance(false);
		v.add(asn1Boolean);
		
		String octs = "i am octString";
		DEROctetString octString = new DEROctetString(octs.getBytes());
		v.add(octString);
		
		String bitS = "i am bitS String";
		DERBitString bitString = new DERBitString(bitS.getBytes());
	//	ASN1BitString bitString = ASN1BitString.
		v.add(bitString);

		String oidS = "1.2.156.10197.1.501";
	//	DERObjectIdentifier.
		ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(oidS);
		v.add(oid);
	//	oid.
		
		String ia5S = "i am IA5 String";
		DERIA5String ia5String = new DERIA5String(ia5S);
		v.add(ia5String);
		
		
		
		if(true){
			String oidSEx = "1.2.156.112600.7.1";
			ASN1ObjectIdentifier oidex = new ASN1ObjectIdentifier(oidSEx);
			String octsEx = "1234567890烟草专卖局";
			DEROctetString octStringEx = new DEROctetString(octsEx.getBytes());
			Extension ex1 = new Extension(oidex, true, octStringEx);
			
			oidSEx = "1.2.156.112600.7.2";
			oidex = new ASN1ObjectIdentifier(oidSEx);
			octsEx = "少数民族名称";
			octStringEx = new DEROctetString(octs.getBytes());
			Extension ex2 = new Extension(oidex, false, octStringEx);
			
			oidSEx = "1.2.156.112600.7.3";
			oidex = new ASN1ObjectIdentifier(oidSEx);
			octsEx = "1234567890English";
			octStringEx = new DEROctetString(octs.getBytes());
			Extension ex3 = new Extension(oidex, false, octStringEx);
			
			
			ASN1EncodableVector vEx = new ASN1EncodableVector();
			vEx.add(ex1);
			vEx.add(ex2);
			vEx.add(ex3);
			DERSequence derEx = new DERSequence(vEx);
			
			v.add(derEx);
		}
		
		DERSequence der = new DERSequence(v);
		byte[] b = der.getEncoded("DER");
		File f = new File("c:/asn1test.dat");
		FileOutputStream fos = new FileOutputStream(f);
		fos.write(b);
		fos.close();
		
	//	ASN1EncodableVector v2 = new ASN1EncodableVector();
		
		
	//	DERSequence der = new DERSequence(v);
	//	v2.add(der);
	//	v2.add(new ASN1Integer(s));
		
	//	org.bouncycastle.asn1.DERGeneralizedTime
		
	//	org.bouncycastle.asn1.ASN1BitString  bitString = ASN1BitString.fromByteArray();
		
		
//		org.bouncycastle.asn1.ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.fromByteArray(arg0)
//		DEROctetString dd;
		
		 
		
	//	DERIA5String ss1 = DERIA5String.fromByteArray(arg0)
		
	//	ASN1String asn1s = ASN1String.class.
		
	//	ASN1Choice aa = null;
		
//		org.bouncycastle.asn1.
		
//		DERSequence der2 = new DERSequence(v2);
		
		
		
//		byte[] b = der2.getEncoded("DER");
//		File f = new File("c:/asn1test.dat");
//		FileOutputStream fos = new FileOutputStream(f);
//		fos.write(b);
//		fos.close();
		
//		File f = new File("d:/ceshi.cer");
//		FileInputStream fis = new FileInputStream(f);
//		byte[] b = new byte[(int)f.length()];
//		fis.read(b);
//		fis.close();

//		ASN1InputStream bIn = new ASN1InputStream(b);
//
//		ASN1Primitive asn1Primitive = bIn.readObject();
//		
//		ASN1Sequence signSequence = (ASN1Sequence) asn1Primitive;  
//		
//		Enumeration secEnum = signSequence.getObjects();
//		
//		while (secEnum.hasMoreElements()) {
//			ASN1Primitive seqObj = (ASN1Primitive) secEnum.nextElement();
//			
//			if(seqObj instanceof ASN1Sequence){
//				System.out.println("yes");
//			}
//			
//			byte[] data = seqObj.getEncoded();
//			System.out.println(data[0]);
//		}

//		while ((asn1Primitive = bIn.readObject()) != null){
//			if(asn1Primitive instanceof ASN1Sequence){
//				ASN1Sequence signSequence = (ASN1Sequence) asn1Primitive;  
//				ASN1Encodable a = signSequence.getObjectAt(0);
//				a.toASN1Primitive().
//
//			}
//		}
		
//		bIn.close();
		
		

	}

}
